package com.las.nogu.controller;

import com.alibaba.fastjson.JSONObject;
import com.las.nogu.commond.Constant;
import com.utils.HttpUtils;
import com.utils.RedisUtils;
import com.utils.StrUtils;
import com.utils.osu.OsuApi2;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/osuapi")
public class OsuController {

    private final Log log = LogFactory.getLog(OsuController.class);

    @RequestMapping("/login")
    public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        HttpSession session = request.getSession();
        String uuid = StrUtils.getUUID();
        session.setAttribute(Constant.OSU_AUTH_TAG + session.getId(), uuid);
        response.sendRedirect("https://osu.ppy.sh/oauth/authorize?state=" + uuid + "&response_type=code&approval_prompt=auto&redirect_uri=" + Constant.API_AUTH_URL + "&client_id=" + Constant.CLIENT_ID);
    }

    @RequestMapping("/auth")
    public void auth(HttpServletRequest request, HttpServletResponse response) throws IOException {
        HttpSession session = request.getSession();
        String codeParam = request.getParameter("code");
        String stateParam = request.getParameter("state");

        Object randCode = session.getAttribute(Constant.OSU_AUTH_TAG + session.getId());
        if (null != randCode && randCode.toString().equals(stateParam)) {
            // 下一步获取OSU用户信息
            String url = "https://osu.ppy.sh/oauth/token";
            Map<String, String> params = new HashMap<>();
            params.put("grant_type", "authorization_code");
            params.put("client_id", Constant.CLIENT_ID);
            params.put("client_secret", Constant.API_SERVER_KEY);
            params.put("redirect_uri", Constant.API_AUTH_URL);
            params.put("code", codeParam);
            String result = HttpUtils.doPost(url, JSONObject.toJSONString(params));
            log.info("osu回调授权结果：" + result);
            JSONObject obj = JSONObject.parseObject(result);
            if (null != obj) {
                String token = obj.getString("access_token");
                log.info("获得TOKEN是：" + token);
                String sessionId = session.getId();
                String userToken = "Bearer " + token;
                //Constant.tokenMap.put(sessionId, userToken);

                // 不再使用服务器内存存储TOKEN，改用Redis
                if (!RedisUtils.hasKey(Constant.OSU_AUTH_TAG + sessionId)) {
                    RedisUtils.set(Constant.OSU_AUTH_TAG + sessionId, userToken, Constant.MAX_SESSION_TIME);
                }
                Map<String, String> params2 = new HashMap<>();
                params2.put("grant_type", "client_credentials");
                params2.put("client_id", Constant.CLIENT_ID);
                params2.put("client_secret", Constant.API_SERVER_KEY);
                params2.put("scope", "public");
                String result2 = HttpUtils.doPost(url, JSONObject.toJSONString(params2));
                log.info("osu回调授权结果2：" + result2);
                JSONObject obj2 = JSONObject.parseObject(result2);
                if (null != obj2) {
                    String token2 = obj2.getString("access_token");
                    String userToken2 = "Bearer " + token2;
                    if (!RedisUtils.hasKey(Constant.OSU_AUTH2_TAG + sessionId)) {
                        RedisUtils.set(Constant.OSU_AUTH2_TAG + sessionId, userToken2, Constant.MAX_SESSION_TIME);
                    }
                }

                Object authToken = RedisUtils.get(Constant.OSU_AUTH_TAG + sessionId);
                if (null != authToken) {
                    // 默认获取用户osu std的信息
                    String userInfo = OsuApi2.getInstanceByToken(authToken.toString()).getMeInfo("osu");
                    log.info("OSU玩家信息：" + userInfo);
                    if (StrUtils.isNotEmpty(userInfo)) {
                        // 解析osu玩家信息并存放cookie
                        JSONObject userObj = JSONObject.parseObject(userInfo);
                        String osuId = userObj.getString("id");
                        String osuSessionId = osuId + "," + sessionId;
                        Cookie cookie = new Cookie("osuSessionId", URLEncoder.encode(osuSessionId, "UTF-8"));
                        session.setAttribute(Constant.USER_INFO, userInfo);
                        session.setAttribute(Constant.MY_SESSION, sessionId);
                        session.setAttribute(osuSessionId, sessionId);
                        cookie.setPath("/");

                        // 最后给cookie和会话设置最大时间
                        cookie.setMaxAge(Constant.MAX_SESSION_TIME);
                        session.setMaxInactiveInterval(Constant.MAX_SESSION_TIME);

                        // 再顺便存入到redis
                        RedisUtils.set(Constant.OSU_LOGIN_TAG + osuId + ":" + osuSessionId, userObj, Constant.MAX_SESSION_TIME);
                        response.addCookie(cookie);
                    }
                }
            }
            response.sendRedirect("/");
        }
    }

}
